/*
 * @Author: Kiro AI Assistant
 * @Date: 2025-01-10
 * @Description: 音乐API服务 - 处理音乐相关的网络请求
 * 迁移自 HzyMvModuleApiUtils 和 HzyMvQqApiUtils
 */

import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../models/music_item_model.dart';
import '../utils/error_handler.dart';
import '../utils/network_utils.dart';
import 'music_api_exception.dart';

/// 音乐API服务
/// 提供音乐搜索、播放链接获取等网络请求功能
/// 支持QQ音乐API集成，包含完整的错误处理和重试机制
class MusicApiService {
  static final MusicApiService _instance = MusicApiService._internal();
  factory MusicApiService() => _instance;
  MusicApiService._internal();

  final Dio _dio = Dio();

  /// 初始化网络配置
  void initialize() {
    _dio.options = BaseOptions(
      connectTimeout: const Duration(seconds: 15),
      receiveTimeout: const Duration(seconds: 30),
      headers: {
        'User-Agent':
            'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36',
      },
    );

    // 添加请求拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        if (kDebugMode) {
          debugPrint('🌐 请求: ${options.method} ${options.uri}');
        }
        handler.next(options);
      },
      onResponse: (response, handler) {
        if (kDebugMode) {
          debugPrint(
              '✅ 响应: ${response.statusCode} ${response.requestOptions.uri}');
        }
        handler.next(response);
      },
      onError: (error, handler) {
        if (kDebugMode) {
          debugPrint('❌ 请求错误: ${error.message}');
        }
        handler.next(error);
      },
    ));

    // 添加重试拦截器
    _dio.interceptors.add(_createRetryInterceptor());
  }

  /// 创建重试拦截器
  Interceptor _createRetryInterceptor() {
    return InterceptorsWrapper(
      onError: (error, handler) async {
        if (error.type == DioExceptionType.connectionTimeout ||
            error.type == DioExceptionType.receiveTimeout ||
            error.type == DioExceptionType.sendTimeout) {
          // 对于超时错误，进行重试
          final retryCount = error.requestOptions.extra['retryCount'] ?? 0;
          if (retryCount < 2) {
            error.requestOptions.extra['retryCount'] = retryCount + 1;
            if (kDebugMode) {
              debugPrint(
                  '🔄 重试请求 (${retryCount + 1}/2): ${error.requestOptions.uri}');
            }

            // 延迟后重试
            await Future.delayed(
                Duration(milliseconds: (500 * (retryCount + 1)).toInt()));

            try {
              final response = await _dio.fetch(error.requestOptions);
              handler.resolve(response);
              return;
            } catch (e) {
              // 重试失败，继续抛出原错误
            }
          }
        }
        handler.next(error);
      },
    );
  }

  /// 搜索音乐数据
  /// [keyword] 搜索关键词
  /// [page] 页码，从1开始
  /// [sourceType] 音乐来源类型，默认为QQ音乐
  Future<List<MusicItemModel>> loadSearchData({
    required String keyword,
    int page = 1,
    String sourceType = 'qq',
  }) async {
    try {
      if (kDebugMode) {
        debugPrint('🔍 搜索音乐: $keyword (页码: $page, 来源: $sourceType)');
      }

      switch (sourceType) {
        case 'qq':
        case 'qq_music':
          return await _searchQQMusic(keyword: keyword, page: page);
        default:
          throw SearchException('不支持的音乐来源: $sourceType');
      }
    } catch (error, stackTrace) {
      NetworkUtils.logError(
          '搜索音乐', error is Exception ? error : Exception(error.toString()));
      ErrorHandler.handleError(error, stackTrace);
      return [];
    }
  }

  /// 获取播放链接
  /// [trackId] 音乐ID
  /// [sourceType] 音乐来源类型
  Future<String> loadStrapTrack({
    required String trackId,
    String sourceType = 'qq',
  }) async {
    try {
      if (kDebugMode) {
        debugPrint('🎵 获取播放链接: $trackId (来源: $sourceType)');
      }

      switch (sourceType) {
        case 'qq':
        case 'qq_music':
          return await _getQQMusicPlayUrl(trackId);
        default:
          throw PlayUrlException('不支持的音乐来源: $sourceType');
      }
    } catch (error, stackTrace) {
      NetworkUtils.logError(
          '获取播放链接', error is Exception ? error : Exception(error.toString()));
      ErrorHandler.handleError(error, stackTrace);
      rethrow;
    }
  }

  /// QQ音乐搜索实现
  /// 完全迁移自原始项目的搜索逻辑
  Future<List<MusicItemModel>> _searchQQMusic({
    required String keyword,
    int page = 1,
  }) async {
    try {
      // 构建搜索URL - 完全按照原始项目的格式
      final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
      final url = 'http://i.y.qq.com/s.music/fcgi-bin/search_for_qq_cp'
          '?g_tk=938407465'
          '&uin=0'
          '&format=jsonp'
          '&inCharset=utf-8'
          '&outCharset=utf-8'
          '&notice=0'
          '&platform=h5'
          '&needNewCode=1'
          '&w=$keyword'
          '&zhidaqu=1'
          '&catZhida=1'
          '&t=0'
          '&flag=1'
          '&ie=utf-8'
          '&sem=1'
          '&aggr=0'
          '&perpage=20'
          '&n=20'
          '&p=$page'
          '&remoteplace=txt.mqq.all'
          '&_=$timestamp'
          '&jsonpCallback=jsonp4';

      final response = await _dio.get(
        url,
        options: Options(
          headers: {
            'Referer': 'https://y.qq.com/',
          },
          responseType: ResponseType.plain,
        ),
      );

      if (response.statusCode == 200 && response.data != null) {
        return _parseQQSearchResponse(response.data);
      }

      return [];
    } catch (error) {
      if (kDebugMode) {
        debugPrint('❌ QQ音乐搜索失败: $error');
      }
      rethrow;
    }
  }

  /// 解析QQ音乐搜索响应
  /// 处理JSONP格式的响应数据
  List<MusicItemModel> _parseQQSearchResponse(String responseData) {
    try {
      // 处理JSONP格式 - 移除jsonp4()包装
      String jsonData = responseData;
      if (jsonData.contains('jsonp4(')) {
        jsonData = jsonData.replaceAll('jsonp4(', '');
        jsonData = jsonData.substring(0, jsonData.length - 1);
      }

      final data = json.decode(jsonData);
      final List<MusicItemModel> results = [];

      if (data['data'] != null &&
          data['data']['song'] != null &&
          data['data']['song']['list'] != null) {
        final songList = data['data']['song']['list'] as List;

        for (final song in songList) {
          try {
            final musicItem = MusicItemModel.fromQQMusic(song);
            results.add(musicItem);
          } catch (error) {
            if (kDebugMode) {
              debugPrint('⚠️ 解析单首歌曲失败: $error');
            }
          }
        }
      }

      if (kDebugMode) {
        debugPrint('✅ 解析搜索结果: ${results.length} 首歌曲');
      }

      return results;
    } catch (error) {
      if (kDebugMode) {
        debugPrint('❌ 解析搜索响应失败: $error');
      }
      return [];
    }
  }

  /// 获取QQ音乐播放链接
  /// 完全迁移自原始项目的获取播放链接逻辑
  Future<String> _getQQMusicPlayUrl(String trackId) async {
    try {
      // 清理trackId前缀
      final cleanTrackId = trackId.replaceAll('qqtrack_', '');

      // 生成随机UIN
      final uin = _generateRandomUin();

      // 构建请求数据 - 完全按照原始项目的格式
      final requestData = {
        "req": {
          "module": "CDN.SrfCdnDispatchServer",
          "method": "GetCdnDispatch",
          "param": {
            "guid": "1535153710",
            "calltype": 0,
            "userip": "",
          }
        },
        "req_0": {
          "module": "vkey.GetVkeyServer",
          "method": "CgiGetVkey",
          "param": {
            "guid": "1535153710",
            "songmid": [cleanTrackId],
            "songtype": [0],
            "uin": uin,
            "loginflag": 1,
            "platform": "20",
          }
        },
        "comm": {
          "uin": uin,
          "format": "json",
          "ct": 24,
          "cv": 0,
        },
      };

      // 构建完整的请求URL
      final jsonString = json.encode(requestData);
      final url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?data=$jsonString';

      // 发送请求 - 使用原始项目的完整请求头
      final response = await _dio.get(
        url,
        options: Options(
          headers: {
            'Referer': 'https://y.qq.com/',
            HttpHeaders.cookieHeader: _getQQMusicCookie(),
            'User-Agent':
                'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36',
          },
          contentType: Headers.textPlainContentType,
          responseType: ResponseType.bytes,
        ),
      );

      // 解析响应
      if (response.statusCode == 200 && response.data != null) {
        return _parseQQPlayUrlResponse(response.data);
      }

      throw PlayUrlException('获取播放链接请求失败',
          originalError: 'HTTP ${response.statusCode}');
    } catch (error) {
      if (kDebugMode) {
        debugPrint('❌ 获取QQ音乐播放链接失败: $error');
      }
      rethrow;
    }
  }

  /// 解析QQ音乐播放链接响应
  /// 处理字节数据并提取播放URL
  String _parseQQPlayUrlResponse(List<int> responseData) {
    try {
      // 将字节数据转换为字符串
      final jsonString = const Utf8Codec().decode(responseData);
      final data = json.decode(jsonString);

      if (data['req_0'] != null) {
        String purl = '';
        String sip = '';
        final req0 = data['req_0'];

        if (req0['data'] != null) {
          final reqData = req0['data'];

          // 获取播放URL路径
          if (reqData['midurlinfo'] != null &&
              reqData['midurlinfo'].length > 0) {
            purl = reqData['midurlinfo'][0]['purl'] ?? '';
          }

          // 获取服务器地址
          if (reqData['sip'] != null && reqData['sip'].length > 0) {
            sip = reqData['sip'][0] ?? '';
          }

          // 组合完整的播放URL
          if (purl.isNotEmpty && sip.isNotEmpty) {
            final playUrl = sip + purl;
            if (kDebugMode) {
              debugPrint('✅ 获取到播放链接: $playUrl');
            }
            return playUrl;
          }
        }
      }

      throw PlayUrlException('响应数据中未找到播放链接');
    } catch (error) {
      if (kDebugMode) {
        debugPrint('❌ 解析播放链接响应失败: $error');
      }
      throw ParseException('解析播放链接失败', originalError: error);
    }
  }

  /// 获取QQ音乐Cookie
  /// 模拟真实的浏览器Cookie以提高请求成功率
  String _getQQMusicCookie() {
    return "pgv_info=ssid=s6158909714; pgv_pvid=1498904698; euin=7KEiNecs7eCl; "
        "login_type=1; psrf_access_token_expiresAt=1717044340; "
        "psrf_musickey_createtime=1709268340; "
        "psrf_qqaccess_token=C728702992921E074D401441E124DC63; "
        "psrf_qqopenid=7B8B4F8661528B6000CC20832937041A; "
        "psrf_qqrefresh_token=016419CBD941FF8BACB6D51431C46194; "
        "psrf_qqunionid=0A848DB4F3A5CE240773A0A680B77A62; "
        "qm_keyst=Q_H_L_5FAXPEjiFaCpgWZMkXYaP20BIg01WPJkTQio1fS5-3IIzKXtPVCb5Wg; "
        "qqmusic_key=Q_H_L_5FAXPEjiFaCpgWZMkXYaP20BIg01WPJkTQio1fS5-3IIzKXtPVCb5Wg; "
        "tmeLoginType=2; uin=593886467; wxopenid=; wxrefresh_token=; wxunionid=; "
        "ptcz=91f2339d0bb69e74ad0b8ff3de9fee38059729ca11bd56607e5031e70cc9418d; "
        "fqm_sessionid=ac43074b-c629-42d9-8ecc-274475bc10b2; _clck=myi79b|1|fjp|0; "
        "fqm_pvqid=677179be-d14c-47d8-84f0-482355236b03; "
        "_qimei_h38=ef2c15a84678a97bb28a763f0300000d017b15; _qimei_q36=; "
        "_qimei_fingerprint=6232087aa8f2c072735cd4a41c142b8d; iip=0; "
        "o_cookie=593886467; pac_uid=1_593886467; "
        "eas_sid=p1W7F072p4f3F1h4P9Z4r3H4u5; "
        "_qimei_uuid42=17b15122520100d34678a97bb28a763fcd6825e99a; "
        "qq_domain_video_guid_verify=32f550ed4fab02b2; RK=tc0M5xWETF";
  }

  /// 生成随机UIN
  /// 完全迁移自原始项目的随机UIN生成逻辑
  String _generateRandomUin() {
    final random = Random.secure();
    final List<int> digits = [];
    for (int i = 0; i < 6; i++) {
      digits.add(random.nextInt(10)); // 0-9
    }
    return digits.join('');
  }

  /// 获取QQ音乐图片URL
  /// 迁移自原始项目的图片URL生成逻辑
  static String getQQImageUrl({
    String? qqImageId,
    String imageType = 'album',
  }) {
    if (qqImageId == null || qqImageId.isEmpty) {
      return '';
    }

    String category = '';
    if (imageType == 'artist') {
      category = 'mid_singer_300';
    } else if (imageType == 'album') {
      category = 'mid_album_800';
    }

    final List<String> pathParts = [category];
    if (qqImageId.length >= 2) {
      pathParts.add(qqImageId[qqImageId.length - 2]);
      pathParts.add(qqImageId[qqImageId.length - 1]);
      pathParts.add(qqImageId);
    }

    final path = pathParts.join('/');
    return "http://imgcache.qq.com/music/photo/$path.jpg";
  }

  /// 格式化音乐时长
  /// 迁移自原始项目的时长格式化逻辑
  static String formatMusicDuration(Duration duration) {
    String formattedTime = '';

    if (duration.inSeconds != 0) {
      formattedTime = (duration.inSeconds % 60).toString().padLeft(2, '0');
    } else {
      formattedTime = "00";
    }

    if (duration.inMinutes != 0) {
      formattedTime =
          "${(duration.inMinutes % 60).toString().padLeft(2, '0')}:$formattedTime";
    } else {
      formattedTime = "00:$formattedTime";
    }

    if (duration.inHours != 0) {
      formattedTime = "${duration.inHours.toString()}:$formattedTime";
    }

    return formattedTime;
  }

  /// 检查网络连接状态
  Future<bool> checkNetworkConnection() async {
    try {
      final response = await _dio.get(
        'https://www.baidu.com',
        options: Options(
          sendTimeout: const Duration(seconds: 5),
          receiveTimeout: const Duration(seconds: 5),
        ),
      );
      return response.statusCode == 200;
    } catch (error) {
      if (kDebugMode) {
        debugPrint('⚠️ 网络连接检查失败: $error');
      }
      return false;
    }
  }

  /// 清理资源
  void dispose() {
    _dio.close();
  }
}
